% Chakram is a subproject of Hexena - Haskell Executable Analyser
% License:			GPL-3
% Maintainer:		Montez Fitzpatrick
% Stability:		Experimental
% Portability:		GHC
% Module:			Hexena.Data.OptionalHeader.DataDirectory

Data Directory basically is a table lookup so that windows can access various
pages.  Data Directories are described as follows.

Directory Entries as defined by WinNT.h: lines (11158-11173)

IMAGE_DIRECTORY_ENTRY_EXPORT          0   (Export Directory)
IMAGE_DIRECTORY_ENTRY_IMPORT          1   (Import Directory)
IMAGE_DIRECTORY_ENTRY_RESOURCE        2   (Resource Directory)
IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   (Exception Directory)
IMAGE_DIRECTORY_ENTRY_SECURITY        4   (Security Directory)
IMAGE_DIRECTORY_ENTRY_BASERELOC       5   (Base Relocation Table)
IMAGE_DIRECTORY_ENTRY_DEBUG           6   (Debug Directory)
IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7   (X86 usage) -- Not Used
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   (Architecture Specific Data)
IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   (RVA of GP)
IMAGE_DIRECTORY_ENTRY_TLS             9   (TLS Directory)
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   (Load Configuration Directory)
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   (Bound Import Directory in headers)
IMAGE_DIRECTORY_ENTRY_IAT            12   (Import Address Table)
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   (Delay Load Import Descriptors)
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   (COM Runtime descriptor)


\begin{code}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
module Hexena.Data.OptionalHeader.DataDirectory 
	(
	-- * Data Structures
	  DataDirectory(..)
	, DirectoryEntry(..)
	, DataEntry(..)
	) where

import Data.Label -- Needs 'fclabels' package
import Data.Word

import Data.Tuple (swap)
import Data.Maybe (fromJust)

data DataDirectory = 
	DataDirectory { _directoryEntryList ::  [DirectoryEntry] } deriving (Show, Eq, Ord)

data DirectoryEntry =
    EXPORT
  | IMPORT
  | RESOURCE 
  | EXCEPTION 
  | SECURITY 
  | BASERELOC 
  | DEBUG 
  | ARCHITECTURE 
  | GLOBALPTR 
  | TLS 
  | LOAD_CONFIG 
  | BOUND_IMPORT 
  | IAT 
  | DELAY_IMPORT 
  | COM_DESCRIPTOR 
  deriving (Show, Eq, Ord)
  
data DataEntry = DataEntry
  { _virtualAddr :: Word32    -- ^ relative virtual address of the table
  , _size :: Word32           -- ^ size of the table in bytes
  } deriving (Show, Eq, Ord)

-- | Automatically derive a lense for the DataDirectory types, providing
--   getters and setters.
mkLabels [''DataDirectory, ''DataEntry]

instance Enum DirectoryEntry where
	fromEnum = fromJust . flip lookup imgDirectoryEntryTable
	toEnum = fromJust . flip lookup (map swap imgDirectoryEntryTable)

-- | Used for generating the proper enum set for Directory Entry.  In this
--   case it would have worked out with a generic derivation.  But, I like to
--   be explicit if it could be confusing, especially since COPYRIGHT (7) is taken
--   out because it is not used.
imgDirectoryEntryTable :: [(DirectoryEntry, Int)]
imgDirectoryEntryTable =
    [ (EXPORT,         0)    -- ^ Export Directory
    , (IMPORT,         1)    -- ^ Import Directory
    , (RESOURCE,       2)    -- ^ Resource Directory
    , (EXCEPTION,      3)    -- ^ Exception Directory
    , (SECURITY,       4)    -- ^ Security Directory (Certificate)
    , (BASERELOC,      5)    -- ^ Base Relocation Table
    , (DEBUG,          6)    -- ^ Debug Directory
    , (ARCHITECTURE,   7)    -- ^ Architecture Specific Data
    , (GLOBALPTR,      8)    -- ^ RVA of GP
    , (TLS,            9)    -- ^ TLS Directory
    , (LOAD_CONFIG,   10)    -- ^ Load Configuration Directory
    , (BOUND_IMPORT,  11)    -- ^ Bound Import Directory in headers
    , (IAT,           12)    -- ^ Import Address Table
    , (DELAY_IMPORT,  13)    -- ^ Delay Load Import Descriptors
    , (COM_DESCRIPTOR,14)    -- ^ COM Runtime descriptor
    ]
\end{code}
